#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>

#define MAX_FILE_LINE 1005

#define MAX_STACK 5005
#define EMPTY -1
#define FULL (MAX_STACK-1)


/* stack type. */
typedef struct Stack 
{
	char data[MAX_STACK];
	int top;

} stack;


/* stack functions implementation. */

void reset(stack* s) 
{
	s->top = EMPTY;
}

int empty(stack* s) 
{
	return (s->top == EMPTY);
}

int full(stack* s) 
{
	return (s->top == FULL);
}


void push(stack* s, char c) 
{

	if (!full(s)) {
		s->top++;
		s->data[s->top] = c;
	}
}

char pop(stack* s)  /* assuming stack is not empty. */
{ 

	char c = s->data[s->top];
	s->top--;
	
	return c;
}

char top(stack* s) /* assuming stack is not empty. */
{ 

	char c = s->data[s->top];
	return c;
}


int print_bad_structure() /* prints 'Bad structure' and returns 0. */
{  
	
	int tmp=0;

	tmp=printf("Bad structure\n");
	assert(tmp == strlen("Bad structure\n"));

	return 0;
}


int main(int argc, char *argv[]) 
{
	
	int i = 0;
	char c;
	char file_line[MAX_FILE_LINE];
	FILE* input_file=NULL;
	stack paren_check_stack;


	if (argc != 2) {
		printf("Error: Wrong number of parameters\n");
		return 1;
	}

	input_file = fopen(argv[1],"r"); 

	if (input_file == NULL) {   
		printf("Error: Could not open the input file (maybe doesn't exist)\n");
		return 1;
	}

	reset(&paren_check_stack);

	while(1) {

		fgets(file_line, MAX_FILE_LINE, input_file);  /* reading a line from input file. */
		if (feof(input_file)) {   /* the last, 'empty line', was read. */
			break;
		}

		for (i=0; i<strlen(file_line); i++) {

			if ( (file_line[i]=='(') || (file_line[i]=='[') || (file_line[i]=='<') || (file_line[i]=='{') )
			{
				push(&paren_check_stack, file_line[i]);  /* left parenthesis - pushing into the stack. */
			}


			if ( (file_line[i]==')') || (file_line[i]==']') || (file_line[i]=='>') || (file_line[i]=='}') )
			{
				if (empty(&paren_check_stack))
				{
					return print_bad_structure();   /* no matching left parenthesis. */

				} else {

					c=pop(&paren_check_stack);

					switch (file_line[i]) {
						case '(': 
							if (c != ')') 
							{
								return print_bad_structure();
							}
							continue;  /* continues the for loop. */

						case ']': 
							if (c != '[') 
							{
								return print_bad_structure();
							}
							continue;

						case '>': 
							if (c != '<') 
							{
								return print_bad_structure();
							}
							continue;

						case '}': 
							if (c != '{') 
							{
								return print_bad_structure();
							}
							continue;

					} /* end of switch. */

				}  /* end of else. */

			} 
	
		} /* end of for. */


	}  /* end of while. */
	

	if (!empty(&paren_check_stack)) /* parentheses balanced iff stack is empty. */
	{
		return print_bad_structure();
	} 
	

	i=printf("Ok\n");
	assert(i == strlen("Ok\n"));

	return 0;

}